package Day_0207.Redis;

/**
 * @author zxc
 * @date 2023/02/07 22:41
 **/
public class Redis_Performance_Issues {
    public static void main(String[] args) {
        /**
         * Redis中的性能问题和解决方案
         * ===》
         * Redis 常见性能问题和解决方案如下：
         * 1.Master（Redis主节点） 最好不要做任何持久化工作，如 RDB 内存快照和 AOF 日志文件;
         *
         * 2.如果数据比较重要，某个 Slave（Redis从节点） 开启 AOF 备份数据，策略设置为每秒同步一次;
         *
         * 3.为了主从复制的速度和连接的稳定性，Master 和 Slave 最好在同一个局域网内;
         *
         * 4.尽量避免在压力很大的主库上增加从库;
         *
         * 5.主从复制不要用图状结构，用单向链表结构更为稳定，即：Master <- Slave1 <- Slave2 <-Slave3….；
         * 这样的结构方便解决单点故障问题，实现 Slave 对 Master 的替换。
         * 如果 Master 挂了，可以立刻启用 Slave1 做 Master，其他不变。
         *
         */

        /**
         * 假如 Redis 里面有 1 亿个 key，其中有 10w 个 key 是以某个固定的已知的前缀开头的，如果将它们全部找出来？
         * ===》
         * 我们可以使用 keys 命令和 scan 命令，但是会发现使用 scan 更好。
         * 1. 使用 keys 命令
         * （1）直接使用 keys 命令查询，但是如果是在生产环境下使用会出现一个问题，keys 命令是遍历查询的，查询的时间复杂度为 O(n)，数据量越大查询时间越长。
         * （2）而且 Redis 是单线程，keys 指令会导致线程阻塞一段时间，会导致线上 Redis 停顿一段时间，直到 keys 执行完毕才能恢复。
         * （3）这在生产环境是不允许的。
         * （4）需要注意的是，这个命令没有分页功能，会一次性查询出所有符合条件的 key 值，会发现查询结果非常大，输出的信息非常多。
         *
         * 2. 使用 scan 命令
         * （1）scan 命令可以实现和 keys 一样的匹配功能，但是 scan 命令在执行的过程不会阻塞线程，并且查找的数据可能存在重复，需要客户端操作去重。
         * （2）因为 scan 是通过游标方式查询的，所以不会导致Redis 出现假死的问题。
         * （3）Redis 查询过程中会把游标返回给客户端，单次返回空值且游标不为 0，则说明遍历还没结束，客户端继续遍历查询。
         * （4）scan 在检索的过程中，被删除的元素是不会被查询出来的，但是如果在迭代过程中有元素被修改，scan 不能保证查询出对应元素。
         * （5）相对来说，scan 指令查找花费的时间会比 keys 指令长。
         *
         */
    }
}
